/*
Libreria ADC ADS1247
ADC 24 bit 8ch single / 4ch Differential
HW TEST 4
Manuel Baldo
10/11/2009
*/
#include "p24HJ256GP206.h"
#include "spi.h"
#include "main.h"
#include "IOpin.h"  // Per funzione UsDelay
#include "ADS1247.h"
//****************************************************************************************************

unsigned long ADC_Out = 0;
unsigned char out[24];
unsigned char count = 0;
unsigned char set_byte=0;
void Init_ADS1247(void)
	{
	TRISGbits.TRISG7  =1;      				 
	TRISBbits.TRISB12 =1;
	TRISGbits.TRISG8  =0;
	TRISGbits.TRISG6  =0;
	TRISBbits.TRISB13 =0;		 
	TRISCbits.TRISC13 =0;
	TRISCbits.TRISC14 =1;
	
	CS_adc=1;
	SCLK_adc=0;
	DIN_adc=0;
	START_pin=0;

	}

void Sync_ADC(void)
	{
	CS_adc = 0;
	START_pin=1;
	Delay_ns(10);		
	Write_Byte(SYNC);
	Write_Byte(SYNC);
	START_pin=0;
	CS_adc = 1;
	}

void Setup_ADS1247(void)
	{

	CS_adc = 0;
	START_pin=1;
	Delay_ns(10);		
	Write_Byte(WREG|MUX1);
	Write_Byte(0);
	Write_Byte(0b00111000);// REF Interno
	START_pin=0;
	CS_adc = 1;
	}


//****************************************************************************************************
void OfsCal_ADS1247(void)
	{
	CS_adc = 0;
	START_pin=1;
	Delay_ns(10);		
	Write_Byte(SELFOCAL);
	UsDelay(100000);
	START_pin=0;
	CS_adc = 1;
	}

unsigned long Read_FSC(void)
	{
	unsigned long fsc[3]={0,0,0};
	unsigned long FSC=0;
	CS_adc = 0;
	START_pin=1;
	Delay_ns(10);		
	Write_Byte(RREG|FSC0);
	Write_Byte(2);
	UsDelay(10);
	fsc[0]=Read_bits(8);
	fsc[1]=Read_bits(8)<<8;
	fsc[2]=Read_bits(8)<<16;
	START_pin=0;
	CS_adc = 1;
	FSC=0;
	FSC=fsc[0]|fsc[1]|fsc[2];
	return FSC;		
	}

unsigned long Read_OFS(void)
	{
	unsigned long ofs[3]={0,0,0};
	unsigned long OFS=0;
	CS_adc = 0;
	START_pin=1;
	Delay_ns(10);		
	Write_Byte(RREG|OFC0);
	Write_Byte(2);
	UsDelay(10);
	ofs[0]=Read_bits(8);
	ofs[1]=Read_bits(8)<<8;
	ofs[2]=Read_bits(8)<<16;
	START_pin=0;
	CS_adc = 1;
	OFS=0;
	OFS=ofs[0]|ofs[1]|ofs[2];
	return OFS;		
	}

unsigned char Read_REG(unsigned char addr)
	{
	unsigned char reg=0;
	CS_adc = 0;
	START_pin=1;
	Delay_ns(10);		
	Write_Byte(RREG|(addr&0x0F));
	Write_Byte(0);
	UsDelay(10);
	reg=Read_bits(8);
	START_pin=0;
	CS_adc = 1;
	return reg;		
	}

void PGA_SPS_ADS1247(unsigned char pga,unsigned int sps) // da 0 a 128
	{
	unsigned char set_pga;
	unsigned char set_sps;

	switch (pga)
		{
		case 1:
		set_pga = 0;		   
		break;

		case 2: 
		set_pga = 1;   
		break;

		case 4:
 		set_pga = 2;
		break;

		case 8:
  		set_pga = 3;		   
		break;

		case 16:
  		set_pga = 4;		   
		break;

		case 32:
  		set_pga = 5;		   
		break;

		case 64:
 		set_pga = 6; 		   
		break;

		case 128:
  		set_pga = 7;		   
		break;

		default:
			return;
		break;
		}

	set_pga = set_pga<<4;
	set_pga = set_pga & 0b01111111;

	switch (sps)
		{
		case 5:
  		set_sps = 0;		   
		break;

		case 10:
  		set_sps = 1;		   
		break;

		case 20:
  		set_sps = 2;		   
		break;

		case 40:
  		set_sps = 3;		   
		break;

		case 80:
  		set_sps = 4;		   
		break;

		case 160:
  		set_sps = 5;		   
		break;

		case 320:
  		set_sps = 6;		   
		break;

		case 640:
  		set_sps = 7;		   
		break;

		case 1000:
  		set_sps = 8;		   
		break;

		case 2000:
  		set_sps = 9;		   
		break;

		default:
			return;
		break;
		}

	
	CS_adc = 0;
	START_pin=1;
	Delay_ns(10);		
	Write_Byte(WREG|SYS0);
	Write_Byte(0);
	set_byte = set_pga|set_sps;
	Write_Byte(set_byte);// 0xxx PGA1 xxxx 160SPS
	START_pin=0;
	CS_adc = 1;
UsDelay(100000);

}

long ADS1247_OUT(unsigned char time_out)
	{
	START_pin=1;
	UsDelay(10);
	START_pin=0;
	Delay_ns(10);
	
	while(DRDY_adc)
		{asm("clrwdt");}

	CS_adc = 0;
	Delay_ns(30); 

	Write_Byte(RDATA);
	Delay_ns(50); 
	ADC_Out = Read_bits(24);

	DIN_adc = 0; 
	CS_adc = 1;	

	return ADC_Out;
	}

void Delay_SCK(void)
	{
	float temp;
	long int cycles=1;
	temp=(float)(cycles*(FREQ/8000000));
	cycles=(long int)temp;
	while(cycles>0)
		{cycles--;}
	return;
	}

void Delay_ns(long ns) 
{  
	unsigned int i;
    for(i=0;i < ns;i++)
        asm("clrwdt");
}

void Write_Byte(unsigned char byte)
{
	unsigned char count = 0;
	for (count=0;count<8;count++) // primi byte richiesta RDATA
		{
		SCLK_adc=1;
		if((byte&(0x80>>count))>0)
			DIN_adc =1;
		else
			DIN_adc =0;
		Delay_SCK();
		SCLK_adc=0;
		Delay_SCK();
		}
}

unsigned long Read_bits(unsigned char bits)
{
	long start_bit = 0;
    ADC_Out=0;
	start_bit = 1;
	start_bit = start_bit<<(bits-1);

	for (count=0;count<bits;count++) 
		{
		SCLK_adc=1;
		DIN_adc = 1; 
		Delay_SCK();
		SCLK_adc=0;
		if(DOUT_adc)
			{
			ADC_Out = ADC_Out|(start_bit>>count);
			}
		Delay_SCK();
		}
		
	return ADC_Out;

}